home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / ODF / OS / FWGraphx / FWColor.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  18.9 KB  |  649 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWColor.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWCOLOR_H
  13. #include "FWColor.h"
  14. #endif
  15.  
  16. #ifndef FWSTDDEF_H
  17. #include "FWStdDef.h"
  18. #endif
  19.  
  20. #ifndef FWSTRMRW_H
  21. #include "FWStrmRW.h"
  22. #endif
  23.  
  24. //========================================================================================
  25. //    RunTime Info
  26. //========================================================================================
  27.  
  28. #ifdef FW_BUILD_MAC
  29. #pragma segment fwgraphx1
  30. #endif
  31.  
  32. //========================================================================================
  33. //    struct FW_CColor
  34. //========================================================================================
  35.  
  36. //----------------------------------------------------------------------------------------
  37. //    FW_CColor::FW_CColor
  38. //----------------------------------------------------------------------------------------
  39.  
  40. FW_CColor::FW_CColor()
  41. {
  42.     fRGB = 0;        // Black
  43. }
  44.  
  45. //----------------------------------------------------------------------------------------
  46. //    FW_CColor::FW_CColor
  47. //----------------------------------------------------------------------------------------
  48.  
  49. FW_CColor::FW_CColor(FW_RGBComponent r, FW_RGBComponent g, FW_RGBComponent b)
  50. {
  51.     SetRGB(r, g, b);
  52. }
  53.  
  54. //----------------------------------------------------------------------------------------
  55. //    FW_CColor::FW_CColor
  56. //----------------------------------------------------------------------------------------
  57.  
  58. FW_CColor::FW_CColor(const FW_CColor& colorFrom, const FW_CColor& colorTo, unsigned short numer, unsigned short denom)
  59. {
  60.     Blend(colorFrom, colorTo, numer, denom);
  61. }
  62.  
  63. #ifdef FW_BUILD_MAC
  64. //----------------------------------------------------------------------------------------
  65. //    FW_CColor::FW_CColor
  66. //----------------------------------------------------------------------------------------
  67.  
  68. FW_CColor::FW_CColor(const RGBColor* rgbPtr)
  69. {
  70.     *this = *rgbPtr;
  71. }
  72. #endif
  73.  
  74. #ifdef FW_BUILD_MAC
  75. //----------------------------------------------------------------------------------------
  76. //    FW_CColor::FW_CColor
  77. //----------------------------------------------------------------------------------------
  78.  
  79. FW_CColor::FW_CColor(const RGBColor& rgb)
  80. {
  81.     *this = rgb;
  82. }
  83. #endif
  84.  
  85. #ifdef FW_BUILD_WIN
  86. //----------------------------------------------------------------------------------------
  87. //    FW_CColor::FW_CColor
  88. //----------------------------------------------------------------------------------------
  89.  
  90. FW_CColor::FW_CColor(COLORREF colorref)
  91. {
  92.     fRGB = colorref;
  93. }
  94. #endif
  95.  
  96. //----------------------------------------------------------------------------------------
  97. //    FW_CColor::FW_CColor
  98. //----------------------------------------------------------------------------------------
  99.  
  100. FW_CColor::FW_CColor(FW_SColor sColor)
  101. {
  102.     fRGB = sColor.fRGB;
  103. }
  104.  
  105. //----------------------------------------------------------------------------------------
  106. //    FW_CColor::FW_CColor
  107. //----------------------------------------------------------------------------------------
  108.  
  109. FW_CColor::FW_CColor(const FW_CColor& color)
  110. {
  111.     fRGB = color.fRGB;
  112. }
  113.  
  114. //----------------------------------------------------------------------------------------
  115. //    FW_CPoint::FW_CPoint
  116. //----------------------------------------------------------------------------------------
  117.  
  118. FW_CColor::FW_CColor(FW_CReadableStream& stream)
  119. {
  120.     Read(stream);
  121. }
  122.  
  123. //----------------------------------------------------------------------------------------
  124. //    FW_CColor::operator=
  125. //----------------------------------------------------------------------------------------
  126.  
  127. FW_CColor& FW_CColor::operator=(FW_SColor sColor)
  128. {
  129.     fRGB = sColor.fRGB;
  130.     return (*this);
  131. }
  132.  
  133. #ifdef FW_BUILD_MAC
  134. //----------------------------------------------------------------------------------------
  135. //    FW_CColor::operator==
  136. //----------------------------------------------------------------------------------------
  137.  
  138. FW_Boolean FW_CColor::operator==(const RGBColor& rgb) const
  139. {
  140.     FW_SColor color;
  141.     FW_PrivSetRGB(color, rgb.red >> 8, rgb.green >> 8, rgb.blue >> 8);
  142.     return color.fRGB == fRGB;
  143. }
  144. #endif
  145.  
  146. #ifdef FW_BUILD_MAC
  147. //----------------------------------------------------------------------------------------
  148. //    FW_CColor::operator=
  149. //----------------------------------------------------------------------------------------
  150.  
  151. FW_CColor& FW_CColor::operator=(const RGBColor& rgb)
  152. {
  153.     SetRGB(rgb.red >> 8, rgb.green >> 8, rgb.blue >> 8);
  154.     return *this;
  155. }
  156. #endif
  157.  
  158. #ifdef FW_BUILD_MAC
  159. //----------------------------------------------------------------------------------------
  160. //    FW_CColor::operator=
  161. //----------------------------------------------------------------------------------------
  162.  
  163. FW_CColor::operator RGBColor() const
  164. {
  165.     RGBColor rgb;
  166.  
  167.     rgb.red     =    FW_PrivRGB_R(*this);
  168.     rgb.red        |=     rgb.red << 8;
  169.     
  170.     rgb.green     =    FW_PrivRGB_G(*this);
  171.     rgb.green    |=    rgb.green << 8;
  172.     
  173.     rgb.blue     =    FW_PrivRGB_B(*this);
  174.     rgb.blue    |=    rgb.blue << 8;
  175.  
  176.     return rgb;
  177. }
  178.  
  179. #endif
  180.  
  181. #ifdef FW_BUILD_WIN
  182. //----------------------------------------------------------------------------------------
  183. //    FW_CColor::operator=
  184. //----------------------------------------------------------------------------------------
  185.  
  186. FW_CColor& FW_CColor::operator=(RGBQUAD quad)
  187. {    
  188.     SetRGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
  189.  
  190.     return *this;
  191. }
  192. #endif
  193.  
  194. #ifdef FW_BUILD_WIN
  195. //----------------------------------------------------------------------------------------
  196. //    FW_CColor::operator=
  197. //----------------------------------------------------------------------------------------
  198.  
  199. FW_CColor::operator RGBQUAD() const
  200. {
  201.     unsigned short r, g, b;
  202.     RGBQUAD quad;
  203.     
  204.     GetRGB(r, g, b);
  205.     
  206.     quad.rgbRed = (FW_RGBComponent)r;
  207.     quad.rgbGreen = (FW_RGBComponent)g;
  208.     quad.rgbBlue = (FW_RGBComponent)b;
  209.     quad.rgbReserved = 0;
  210.     
  211.     return quad;
  212. }
  213. #endif
  214.  
  215. #ifdef FW_BUILD_WIN
  216. //----------------------------------------------------------------------------------------
  217. //    FW_CColor::operator=
  218. //----------------------------------------------------------------------------------------
  219.  
  220. FW_CColor& FW_CColor::operator=(RGBTRIPLE triple)
  221. {    
  222.     SetRGB(triple.rgbtRed, triple.rgbtGreen, triple.rgbtBlue);
  223.  
  224.     return *this;
  225. }
  226. #endif
  227.  
  228. #ifdef FW_BUILD_WIN
  229. //----------------------------------------------------------------------------------------
  230. //    FW_CColor::operator=
  231. //----------------------------------------------------------------------------------------
  232.  
  233. FW_CColor::operator RGBTRIPLE() const
  234. {
  235.     unsigned short r, g, b;
  236.     RGBTRIPLE triple;
  237.     
  238.     GetRGB(r, g, b);
  239.     
  240.     triple.rgbtRed = (FW_RGBComponent)r;
  241.     triple.rgbtGreen = (FW_RGBComponent)g;
  242.     triple.rgbtBlue = (FW_RGBComponent)b;
  243.     
  244.     return triple;
  245. }
  246. #endif
  247.  
  248. //----------------------------------------------------------------------------------------
  249. //    FW_CColor::operator=
  250. //----------------------------------------------------------------------------------------
  251.  
  252. FW_CColor& FW_CColor::operator=(const FW_CColor& color)
  253. {
  254.     fRGB = color.fRGB;
  255.     return *this;
  256. }
  257.  
  258. //----------------------------------------------------------------------------------------
  259. // Arithmetic, by another color for FW_CColor
  260. // Only + and - really make sense for FW_CColor operands, but multiply and divide
  261. // exist for consistency, since they do make sense for scalars
  262. //----------------------------------------------------------------------------------------
  263.  
  264. //----------------------------------------------------------------------------------------
  265. //    FW_CColor::AddComponents
  266. //----------------------------------------------------------------------------------------
  267.  
  268. inline
  269. FW_RGBComponent AddComponents(unsigned short a, unsigned short b)
  270. {
  271.     a += b;
  272.  
  273.     if (a > 255)
  274.         a = 255;
  275.     
  276.     return (FW_RGBComponent)a;
  277. }
  278.  
  279. //----------------------------------------------------------------------------------------
  280. //    FW_CColor::SubtractComponents
  281. //----------------------------------------------------------------------------------------
  282.  
  283. inline
  284. FW_RGBComponent SubtractComponents(unsigned short a, unsigned short b)
  285. {
  286.     return (FW_RGBComponent)(a <= b ? 0 : a - b);
  287. }
  288.  
  289. //----------------------------------------------------------------------------------------
  290. //    FW_CColor::MultiplyComponents
  291. //----------------------------------------------------------------------------------------
  292.  
  293. inline
  294. FW_RGBComponent MultiplyComponents(unsigned short a, unsigned short b)
  295. {
  296.     a *= b;
  297.  
  298.     if (a > 255)
  299.         a = 255;
  300.  
  301.     return (FW_RGBComponent)a;
  302. }
  303.  
  304. //----------------------------------------------------------------------------------------
  305. //    FW_CColor::DivideComponents
  306. //----------------------------------------------------------------------------------------
  307.  
  308. inline
  309. FW_RGBComponent DivideComponents(unsigned short a, unsigned short b)
  310. {
  311.     return (FW_RGBComponent)(b == 0 ? 255 : a / b);
  312. }
  313.  
  314. //----------------------------------------------------------------------------------------
  315. //    FW_CColor::AverageComponents
  316. //----------------------------------------------------------------------------------------
  317.  
  318. inline
  319. FW_RGBComponent AverageComponents(unsigned short a, unsigned short b)
  320. {
  321.     return (FW_RGBComponent)((a + b) / 2);
  322. }
  323.  
  324. //----------------------------------------------------------------------------------------
  325. //    FW_CColor::BlendComponents
  326. //----------------------------------------------------------------------------------------
  327.  
  328. inline
  329. FW_RGBComponent BlendComponents(unsigned short a, unsigned short b, unsigned short numer, unsigned short denom)
  330. {
  331.     return (FW_RGBComponent)(a + ((((long) b - a) * numer) / denom));
  332. }
  333.  
  334. //----------------------------------------------------------------------------------------
  335. //    FW_CColor::operator+
  336. //----------------------------------------------------------------------------------------
  337.  
  338. FW_CColor FW_CColor::operator+(const FW_CColor& color) const
  339. {
  340.     FW_CColor newColor(*this);
  341.     return newColor += color;
  342. }
  343.  
  344. //----------------------------------------------------------------------------------------
  345. //    FW_CColor::operator-
  346. //----------------------------------------------------------------------------------------
  347.  
  348. FW_CColor FW_CColor::operator -(const FW_CColor& color) const
  349. {
  350.     FW_CColor newColor(*this);
  351.     return newColor -= color;
  352. }
  353.  
  354. //----------------------------------------------------------------------------------------
  355. //    FW_CColor::operator +=
  356. //----------------------------------------------------------------------------------------
  357.  
  358. FW_CColor& FW_CColor::operator+=(const FW_CColor& color)
  359. {
  360.     unsigned short red1, green1, blue1, red2, green2, blue2;
  361.  
  362.     GetRGB(red1, green1, blue1);
  363.     color.GetRGB(red2, green2, blue2);
  364.     
  365.     SetRGB(AddComponents(red1, red2), AddComponents(green1, green2), AddComponents(blue1, blue2));
  366.  
  367.     return *this;
  368. }
  369.  
  370. //----------------------------------------------------------------------------------------
  371. //    FW_CColor::operator -=
  372. //----------------------------------------------------------------------------------------
  373.  
  374. FW_CColor& FW_CColor::operator-=(const FW_CColor& color)
  375. {
  376.     unsigned short red1, green1, blue1, red2, green2, blue2;
  377.  
  378.     GetRGB(red1, green1, blue1);
  379.     color.GetRGB(red2, green2, blue2);
  380.     
  381.     SetRGB(SubtractComponents(red1, red2), SubtractComponents(green1, green2), SubtractComponents(blue1, blue2));
  382.  
  383.     return *this;
  384. }
  385.  
  386. //----------------------------------------------------------------------------------------
  387. //    FW_CColor::operator +
  388. //----------------------------------------------------------------------------------------
  389.  
  390. FW_CColor FW_CColor::operator+(unsigned short aScalar) const
  391. {
  392.     FW_CColor newColor(*this);
  393.  
  394.     return (newColor += aScalar);
  395. }
  396.  
  397. //----------------------------------------------------------------------------------------
  398. //    FW_CColor::operator -
  399. //----------------------------------------------------------------------------------------
  400.  
  401. FW_CColor FW_CColor::operator-(unsigned short aScalar) const
  402. {
  403.     FW_CColor newColor(*this);
  404.  
  405.     return (newColor -= aScalar);
  406. }
  407.  
  408. //----------------------------------------------------------------------------------------
  409. //    FW_CColor::operator *
  410. //----------------------------------------------------------------------------------------
  411.  
  412. FW_CColor FW_CColor::operator*(unsigned short aScalar) const
  413. {
  414.     FW_CColor newColor(*this);
  415.  
  416.     return (newColor *= aScalar);
  417. }
  418.  
  419. //----------------------------------------------------------------------------------------
  420. //    FW_CColor::operator /
  421. //----------------------------------------------------------------------------------------
  422.  
  423. FW_CColor FW_CColor::operator/(unsigned short aScalar) const
  424. {
  425.     FW_CColor newColor(*this);
  426.  
  427.     return (newColor /= aScalar);
  428. }
  429.  
  430. //----------------------------------------------------------------------------------------
  431. //    FW_CColor::operator +=
  432. //----------------------------------------------------------------------------------------
  433.  
  434. FW_CColor& FW_CColor::operator+=(unsigned short aScalar)
  435. {
  436.     unsigned short red, green, blue;
  437.  
  438.     GetRGB(red, green, blue);
  439.     
  440.     SetRGB(AddComponents(red, aScalar), 
  441.             AddComponents(green, aScalar), 
  442.             AddComponents(blue, aScalar));
  443.  
  444.     return *this;
  445. }
  446.  
  447. //----------------------------------------------------------------------------------------
  448. //    FW_CColor::operator -=
  449. //----------------------------------------------------------------------------------------
  450.  
  451. FW_CColor& FW_CColor::operator-=(unsigned short aScalar)
  452. {
  453.     unsigned short red, green, blue;
  454.  
  455.     GetRGB(red, green, blue);
  456.     
  457.     SetRGB(SubtractComponents(red, aScalar), 
  458.             SubtractComponents(green, aScalar), 
  459.             SubtractComponents(blue, aScalar));
  460.  
  461.     return *this;
  462. }
  463.  
  464. //----------------------------------------------------------------------------------------
  465. //    FW_CColor::operator *=
  466. //----------------------------------------------------------------------------------------
  467.  
  468. FW_CColor& FW_CColor::operator*=(unsigned short aScalar)
  469. {
  470.     unsigned short red, green, blue;
  471.  
  472.     GetRGB(red, green, blue);
  473.     
  474.     SetRGB(
  475.         MultiplyComponents(red, aScalar), 
  476.         MultiplyComponents(green, aScalar), 
  477.         MultiplyComponents(blue, aScalar)
  478.     );
  479.  
  480.     return *this;
  481. }
  482.  
  483. //----------------------------------------------------------------------------------------
  484. //    FW_CColor::operator /=
  485. //----------------------------------------------------------------------------------------
  486.  
  487. FW_CColor& FW_CColor::operator/=(unsigned short aScalar)
  488. {
  489.     unsigned short red, green, blue;
  490.  
  491.     GetRGB(red, green, blue);
  492.     
  493.     SetRGB(
  494.         DivideComponents(red, aScalar), 
  495.         DivideComponents(green, aScalar), 
  496.         DivideComponents(blue, aScalar)
  497.     );
  498.  
  499.     return *this;
  500. }
  501.  
  502. //----------------------------------------------------------------------------------------
  503. //    FW_CColor::Brightness
  504. //----------------------------------------------------------------------------------------
  505.  
  506. unsigned long FW_CColor::Brightness() const
  507. {
  508.     unsigned short red, green, blue;
  509.  
  510.     GetRGB(red, green, blue);
  511.  
  512.     // calculate approximate brightness using YIQ formula where
  513.     // Y = lumenance = .30R + .59G + .11B
  514.     // approx. fY := (r / 4) + 5 * (g / 8) + b / 8 ≈ (.25 R + .625 G + .125 B)
  515.  
  516.     return (red >> 2) + (5L * (green >> 3)) + (blue >> 3);
  517. }
  518.  
  519. //----------------------------------------------------------------------------------------
  520. //    FW_CColor::IsDarkerThan
  521. //----------------------------------------------------------------------------------------
  522.  
  523. FW_Boolean FW_CColor::IsDarkerThan(const FW_CColor& color) const
  524. {
  525.     return Brightness() < color.Brightness();
  526. }
  527.  
  528. //----------------------------------------------------------------------------------------
  529. //    FW_CColor::IsLighterThan
  530. //----------------------------------------------------------------------------------------
  531.  
  532. FW_Boolean FW_CColor::IsLighterThan(const FW_CColor& color) const
  533. {
  534.     return Brightness() > color.Brightness();
  535. }
  536.  
  537. //----------------------------------------------------------------------------------------
  538. //    FW_CColor::Average
  539. //----------------------------------------------------------------------------------------
  540.  
  541. FW_CColor& FW_CColor::Average(const FW_CColor& colorA, const FW_CColor& colorB)
  542. {
  543.     unsigned short redA, greenA, blueA;
  544.     unsigned short redB, greenB, blueB;
  545.  
  546.     colorA.GetRGB(redA, greenA, blueA);
  547.     colorB.GetRGB(redB, greenB, blueB);
  548.  
  549.     SetRGB(AverageComponents(redA, redB), 
  550.             AverageComponents(greenA, greenB), 
  551.             AverageComponents(blueA, blueB));
  552.  
  553.     return *this;
  554. }
  555.  
  556. //----------------------------------------------------------------------------------------
  557. //    FW_CColor::Average
  558. //----------------------------------------------------------------------------------------
  559.  
  560. FW_CColor& FW_CColor::Blend(const FW_CColor& colorFrom, const FW_CColor& colorTo, unsigned short numer, unsigned short denom)
  561. {
  562.     unsigned short redA, greenA, blueA;
  563.     unsigned short redB, greenB, blueB;
  564.  
  565.     colorFrom.GetRGB(redA, greenA, blueA);
  566.     colorTo.GetRGB(redB, greenB, blueB);
  567.  
  568.     if (numer == 0)
  569.     {
  570.         SetRGB((FW_RGBComponent)redA, (FW_RGBComponent)greenA, (FW_RGBComponent)blueA);
  571.     }
  572.     else if (numer >= denom || denom == 0)
  573.     {
  574.         SetRGB((FW_RGBComponent)redB, (FW_RGBComponent)greenB, (FW_RGBComponent)blueB);
  575.     }
  576.     else
  577.     {
  578.         SetRGB(
  579.             BlendComponents(redA, redB, numer, denom),
  580.             BlendComponents(greenA, greenB, numer, denom),
  581.             BlendComponents(blueA, blueB, numer, denom));
  582.     }
  583.  
  584.     return *this;
  585. }
  586.  
  587. //----------------------------------------------------------------------------------------
  588. //    FW_CColor::SetRGB
  589. //----------------------------------------------------------------------------------------
  590.  
  591. void FW_CColor::SetRGB(FW_RGBComponent r, FW_RGBComponent g, FW_RGBComponent b)
  592. {
  593.     FW_PrivSetRGB(*this, r, g, b);
  594. }
  595.  
  596. //----------------------------------------------------------------------------------------
  597. //    FW_CColor::GetRGB
  598. //----------------------------------------------------------------------------------------
  599.  
  600. void FW_CColor::GetRGB(unsigned short& r, unsigned short& g, unsigned short& b) const
  601. {
  602.     r = FW_PrivRGB_R(*this);
  603.     g = FW_PrivRGB_G(*this);
  604.     b = FW_PrivRGB_B(*this);
  605. }
  606.  
  607. //----------------------------------------------------------------------------------------
  608. //    FW_CColor::Read
  609. //----------------------------------------------------------------------------------------
  610.  
  611. void FW_CColor::Read(FW_CReadableStream& stream)
  612. {
  613.     unsigned short rgb[3];
  614.     stream.Read(rgb, 3);
  615.     SetRGB((FW_RGBComponent)rgb[0], (FW_RGBComponent)rgb[1], (FW_RGBComponent)rgb[2]);
  616. }
  617.  
  618. //----------------------------------------------------------------------------------------
  619. //    FW_CColor::Write
  620. //----------------------------------------------------------------------------------------
  621.  
  622. void FW_CColor::Write(FW_CWritableStream& stream) const
  623. {
  624.     unsigned short rgb[3];
  625.     GetRGB(rgb[0], rgb[1], rgb[2]);    
  626.     stream.Write(rgb, 3);
  627. }
  628.  
  629. //----------------------------------------------------------------------------------------
  630. //    operator>>
  631. //----------------------------------------------------------------------------------------
  632.  
  633. FW_CReadableStream& operator>>(FW_CReadableStream& stream, FW_CColor& color)
  634. {
  635.     color.Read(stream);
  636.     return stream;
  637. }
  638.  
  639. //----------------------------------------------------------------------------------------
  640. //    operator<<
  641. //----------------------------------------------------------------------------------------
  642.  
  643. FW_CWritableStream& operator<<(FW_CWritableStream& stream, const FW_CColor& color)
  644. {
  645.     color.Write(stream);    
  646.     return stream;
  647. }
  648.  
  649.